<?php

namespace lc\activity;

use lc\activity\model\LotteryRedPackConfig;
use lc\wechat\wxpay\WxPayApi;

/**
 * @desc    红包发放类
 * @package lc\activity
 */
class RedPackAct
{
    /**
     * @var 红包活动 APPID
     */
    private $appId = 0;

    /**
     * @var 红包活动 APP_SECRET
     */
    private $appSecret = '';

    /**
     * @var 红包活动 PID
     */
    private $pid = 0;

    /**
     * @var 抽奖活动配置
     */
    private $config;

    public function setPid(int $pid)
    {
        $this->pid = $pid;
    }

    public function setAppid(string $appid, string $appSecret)
    {
        $this->appId 	 = $appid;
        $this->appSecret = $appSecret;
    }

    /*
     * @desc    发放红包
     * @param   array   $user   用户信息
     * @param   int     $money  红包金额
     * @return  array
     * @throws  \lc\wxpay\base\WxPayException
     * @throws  \think\db\exception\DbException
     */
    public function send(array $user, int $money): array
    {
        if ($check = $this->redPackStartOrEnd()) {
            return $check;
        }

        if ($this->config->l_type == LotteryRedPackConfig::RED_PACK_TYPE_CASH) {
            $result = $this->sendRedPackByCash($user, $money);
        } else {
            $result = $this->sendRedPackByBalance($user, $money);
        }
        if ($result['status'] == 1) {
            LotteryRedPackConfig::connect('main')
                ->where('l_id', $this->config->l_id)
                ->inc('l_revc_money', $money)
                ->save();
        }
        return $result;
    }

    /**
     * @desc 判断活动是否未开始或已结束
     */
    private function redPackStartOrEnd()
    {
        if ($this->pid) {
            $config = LotteryRedPackConfig::connect('main')->where('l_pid', $this->pid)->find();
        } else {
            $config = LotteryRedPackConfig::connect('main')->where('l_appid', $this->appId)->find();
        }
        if (!$config) {
            return ['status' => 0, 'msg' => 'APPID 或 PID 错误，未匹配到红包活动.'];
        }
        if ($this->appSecret && $this->appSecret != $config->l_secret) {
            return ['status' => 0, 'msg' => 'APPID 与 APP_SECRET 不匹配.'];
        }
        if ($config->l_check != 1) {
            return ['status' => 0, 'msg' => '活动未审核或未通过审核，无法发放红包.'];
        }
        if (strtotime($config->l_start_time) > time()) {
            return ['status' => 0, 'msg' => "活动于 {$config->l_start_time} 正式开始."];
        }
        if (strtotime($config->l_end_time) < time()) {
            return ['status' => 0, 'msg' => "活动于 {$config->l_end_time} 已结束，敬请期待下次活动."];
        }
        $this->config = $config;
    }

    /*
     * @desc    发红包，红包发放失败则直接不中奖
     * @param   array   $userInfo   用户信息
     * @param   double  $money      红包金额，单位：分
     * @return  array
     * @throws  \lc\wxpay\base\WxPayException
     * @throws  \think\db\exception\DbException
     */
    private function sendRedPackByCash($userInfo, $money)
    {
        $redPack = json_decode($this->config->l_redpack);
        if (empty($redPack->act_name) || empty($redPack->send_name) || empty($redPack->wishing) || empty($redPack->remark)) {
            return ['status' => 0, 'msg' => '红包配置异常，请检查 l_repack 参数'];
        }

        try {
            $openid  = $userInfo['u_openid'];
            $orderNo = $this->config->l_pid . date('YmdHis') . mt_rand(1000, 9999) . mt_rand(1000, 9999); // 长度28位
            $input   = [
				'mch_billno' 	=> $orderNo,
				'total_amount' 	=> $money,
				're_openid' 	=> $openid,
				'send_name' 	=> $redPack->send_name,
				'wishing' 		=> $redPack->wishing,
				'act_name' 		=> $redPack->act_name,
				'remark' 		=> $redPack->remark,
				'total_num' 	=> 1
			];
			if (!empty($redPack->scene_id) && $redPack->scene_id != 'PRODUCT_0') {
				$input['scene_id'] = $redPack->scene_id;
			}
            $result = WxPayApi::sendRedPack($input);
            $this->resultSmsNotify($result);

            $success = 0;
            if (isset($result['result_code']) && $result['result_code'] == 'SUCCESS'
                || isset($result['err_code']) && $result['err_code'] == 'SYSTEMERROR') {
                $success = 1;
            }

            return [
                'status' => $success,
                'msg'    => $success ? $result['result_code'] : $result['err_code_des'],
                'data'   => $success ? $input : [],
                'result' => $result
            ];
        } catch (\RuntimeException $e) {
            return ['status' => 0, 'msg' => $e->getMessage(), 'data' => []];
        }
    }

    /*
     * @desc    企业支付到零钱，现金红包发放
     * @param   array   $userInfo   用户信息
     * @param   int     $money      红包金额，单位：分
     * @return  array
     * @throws  \lc\wxpay\base\WxPayException
     * @throws  \think\db\exception\DbException
     */
    private function sendRedPackByBalance($userInfo, $money)
    {
        $redPack = json_decode($this->config->l_redpack);
        if (empty($redPack->description) || empty($redPack->if_check_name)) {
            return ['status' => 0, 'msg' => '红包配置异常，请检查 l_repack 参数'];
        }

        $nick    = $userInfo['u_nick'];
        $orderNo = $this->config->l_pid . date('YmdHis') . mt_rand(100000, 999999) . mt_rand(1000, 9999); // 长度32位
        try {
            $data = [
                'partner_trade_no' 	=> $orderNo,
                'check_name' 		=> $redPack->if_check_name,
                're_user_name' 		=> ($redPack->if_check_name == 'FORCE_CHECK') ? $userInfo['u_name'] : $nick,
                'amount' 			=> $money,
                'desc' 				=> $redPack->description,
                'openid' 			=> $userInfo['u_openid']
            ];
            $result = WxPayApi::payToBalance($data);
            $this->resultSmsNotify($result);

            $success = 0;
            if (isset($result['result_code']) && $result['result_code'] == 'SUCCESS'
                || isset($result['err_code']) && $result['err_code'] == 'SYSTEMERROR') {
                $success = 1;
            }
            return [
                'status' => $success,
                'msg'    => $success ? $result['result_code'] : $result['err_code_des'],
                'data'   => $success ? $data : [],
                'result' => $result
            ];
        } catch (\RuntimeException $e) {
            return ['status' => 0, 'msg' => $e->getMessage(), 'data' => []];
        }
    }

    /*
     * @desc    针对发红包接口的报警通知
     * @param   array   $result 请求数据
     * @throws  \think\db\exception\DbException
     */
    private function resultSmsNotify($result)
    {
        if (isset($result['err_code']) && $this->config->l_notify_phone) {
            switch ($result['err_code']) {
                case 'MONEY_LIMIT':
                case 'NOTENOUGH':
                case 'CA_ERROR':
                case 'FREQ_LIMIT':
                case 'SENDAMOUNT_LIMIT':
                    $phones = explode('|', $this->config->l_notify_phone);
                    if ($phones) {
                        foreach ($phones as $phone) {
                            $sms = new SmsAct('sms202005738162', 'e8c0341ce1bfd29666fbb726e00e87c76edcbce1');
                            $sms->send($phone, ['name' => $this->config->l_pid, 'code' => $result['err_code'] . $result['err_code_des']]);
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }
}